using System;
using System.Threading;
using ComponentSystem;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Audio;

namespace ZYFramework.AudioSystem
{
    /// <summary>
    /// 音频全局控制组件
    /// </summary>
    public class Com_AudioGlobalControl : ComponentWithId
    {
        /// <summary>
        /// AudioMixer引用
        /// </summary>
        private AudioMixer _audioMixer;

        /// <summary>
        /// BGM音量参数名称
        /// </summary>
        private string _bgmVolumeParameterName;

        /// <summary>
        /// SFX_2D音量参数名称
        /// </summary>
        private string _sfx2DVolumeParameterName;

        /// <summary>
        /// SFX_3D音量参数名称
        /// </summary>
        private string _sfx3DVolumeParameterName;

        /// <summary>
        /// 当前BGM音量（0-1）
        /// </summary>
        private float _currentBGMVolume = 1f;

        /// <summary>
        /// 当前SFX_2D音量（0-1）
        /// </summary>
        private float _currentSFX2DVolume = 1f;

        /// <summary>
        /// 当前SFX_3D音量（0-1）
        /// </summary>
        private float _currentSFX3DVolume = 1f;

        /// <summary>
        /// BGM是否静音
        /// </summary>
        private bool _isBGMMuted = false;

        /// <summary>
        /// SFX_2D是否静音
        /// </summary>
        private bool _isSFX2DMuted = false;

        /// <summary>
        /// SFX_3D是否静音
        /// </summary>
        private bool _isSFX3DMuted = false;

        protected override void Awake()
        {
            base.Awake();
        }

        protected override void Start()
        {
            base.Start();
        }

        /// <summary>
        /// 初始化全局控制
        /// </summary>
        /// <param name="config">框架配置</param>
        public void Initialize(AudioConfig config)
        {
            if (config.AudioMixer == null)
            {
                Debug.LogWarning("[AudioGlobalControl] AudioMixer未配置，音量控制功能将不可用");
                return;
            }

            this._audioMixer = config.AudioMixer;
            this._bgmVolumeParameterName = config.BGMVolumeParameterName;
            this._sfx2DVolumeParameterName = config.SFX2DVolumeParameterName;
            this._sfx3DVolumeParameterName = config.SFX3DVolumeParameterName;

            // 设置初始音量
            SetGlobalVolume(AudioType.BGM, _currentBGMVolume);
            SetGlobalVolume(AudioType.SFX_2D, _currentSFX2DVolume);
            SetGlobalVolume(AudioType.SFX_3D, _currentSFX3DVolume);
        }

        /// <summary>
        /// 设置全局音量（按类型）
        /// </summary>
        /// <param name="audioType">音频类型</param>
        /// <param name="volume">音量值（0-1）</param>
        public void SetGlobalVolume(AudioType audioType, float volume)
        {
            volume = Mathf.Clamp01(volume);

            string parameterName = GetVolumeParameterName(audioType);
            if (string.IsNullOrEmpty(parameterName) || _audioMixer == null)
            {
                return;
            }

            // 将0-1的volume转换为-80到0的dB值
            float dbValue = volume > 0.0001f ? Mathf.Log10(volume) * 20f : -80f;
            dbValue = Mathf.Clamp(dbValue, -80f, 0f);

            if (_audioMixer.SetFloat(parameterName, dbValue))
            {
                // 更新当前音量值
                switch (audioType)
                {
                    case AudioType.BGM:
                        _currentBGMVolume = volume;
                        break;
                    case AudioType.SFX_2D:
                        _currentSFX2DVolume = volume;
                        break;
                    case AudioType.SFX_3D:
                        _currentSFX3DVolume = volume;
                        break;
                }
            }
            else
            {
                Debug.LogError($"[AudioGlobalControl] 设置音量参数失败: {parameterName}");
            }
        }

        /// <summary>
        /// 获取全局音量（按类型）
        /// </summary>
        /// <param name="audioType">音频类型</param>
        /// <returns>音量值（0-1）</returns>
        public float GetGlobalVolume(AudioType audioType)
        {
            switch (audioType)
            {
                case AudioType.BGM:
                    return _currentBGMVolume;
                case AudioType.SFX_2D:
                    return _currentSFX2DVolume;
                case AudioType.SFX_3D:
                    return _currentSFX3DVolume;
                default:
                    return 1f;
            }
        }

        /// <summary>
        /// 静音/取消静音（按类型）
        /// </summary>
        /// <param name="audioType">音频类型</param>
        /// <param name="isMute">是否静音</param>
        public void MuteAudio(AudioType audioType, bool isMute)
        {
            string parameterName = GetVolumeParameterName(audioType);
            if (string.IsNullOrEmpty(parameterName) || _audioMixer == null)
            {
                return;
            }

            float dbValue = isMute ? -80f : GetMuteDbValue(audioType);

            if (_audioMixer.SetFloat(parameterName, dbValue))
            {
                // 更新静音状态
                switch (audioType)
                {
                    case AudioType.BGM:
                        _isBGMMuted = isMute;
                        break;
                    case AudioType.SFX_2D:
                        _isSFX2DMuted = isMute;
                        break;
                    case AudioType.SFX_3D:
                        _isSFX3DMuted = isMute;
                        break;
                }
            }
            else
            {
                Debug.LogError($"[AudioGlobalControl] 设置静音参数失败: {parameterName}");
            }
        }

        /// <summary>
        /// 检查是否静音
        /// </summary>
        /// <param name="audioType">音频类型</param>
        /// <returns>是否静音</returns>
        public bool IsMuted(AudioType audioType)
        {
            switch (audioType)
            {
                case AudioType.BGM:
                    return _isBGMMuted;
                case AudioType.SFX_2D:
                    return _isSFX2DMuted;
                case AudioType.SFX_3D:
                    return _isSFX3DMuted;
                default:
                    return false;
            }
        }

        /// <summary>
        /// BGM淡入
        /// </summary>
        /// <param name="audioSource">AudioSource</param>
        /// <param name="fadeTime">淡入时间（秒）</param>
        /// <param name="targetVolume">目标音量（0-1），如果不指定则使用audioSource的当前音量</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask FadeInBGMAsync(AudioSource audioSource, float fadeTime, float? targetVolume = null, CancellationToken ct = default)
        {
            if (audioSource == null)
            {
                return;
            }

            // 如果未指定目标音量，则从audioSource获取（但此时应该已经设置了）
            float finalTargetVolume = targetVolume ?? audioSource.volume;
            float elapsedTime = 0f;
            float startVolume = 0f;

            // 确保初始音量为0
            audioSource.volume = startVolume;

            try
            {
                while (elapsedTime < fadeTime && !ct.IsCancellationRequested)
                {
                    elapsedTime += Time.deltaTime;
                    float t = Mathf.Clamp01(elapsedTime / fadeTime);
                    audioSource.volume = Mathf.Lerp(startVolume, finalTargetVolume, t);

                    await UniTask.Yield(PlayerLoopTiming.Update, ct);
                }

                if (!ct.IsCancellationRequested)
                {
                    audioSource.volume = finalTargetVolume;
                }
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[AudioGlobalControl] BGM淡入异常: {e.Message}");
            }
        }

        /// <summary>
        /// BGM淡出
        /// </summary>
        /// <param name="fadeTime">淡出时间（秒）</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask FadeOutBGMAsync(float fadeTime, CancellationToken ct = default)
        {
            // 获取当前BGM的AudioSource（需要通过其他方式获取）
            // 这里暂时使用全局控制的方式来淡出
            // 实际的AudioSource应该由AudioPlayController提供

            float elapsedTime = 0f;
            float startVolume = 1f;

            try
            {
                while (elapsedTime < fadeTime && !ct.IsCancellationRequested)
                {
                    elapsedTime += Time.deltaTime;
                    float t = Mathf.Clamp01(elapsedTime / fadeTime);
                    float currentVolume = Mathf.Lerp(startVolume, 0f, t);

                    // 通过AudioMixer淡出BGM音量
                    float dbValue = currentVolume > 0.0001f ? Mathf.Log10(currentVolume) * 20f : -80f;
                    dbValue = Mathf.Clamp(dbValue, -80f, 0f);

                    if (_audioMixer != null && !string.IsNullOrEmpty(_bgmVolumeParameterName))
                    {
                        _audioMixer.SetFloat(_bgmVolumeParameterName, dbValue);
                    }

                    await UniTask.Yield(PlayerLoopTiming.Update, ct);
                }

                if (!ct.IsCancellationRequested && _audioMixer != null && !string.IsNullOrEmpty(_bgmVolumeParameterName))
                {
                    _audioMixer.SetFloat(_bgmVolumeParameterName, -80f);
                }
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[AudioGlobalControl] BGM淡出异常: {e.Message}");
            }
        }

        /// <summary>
        /// BGM淡出（指定AudioSource）
        /// </summary>
        /// <param name="audioSource">AudioSource</param>
        /// <param name="fadeTime">淡出时间（秒）</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask FadeOutBGMAsync(AudioSource audioSource, float fadeTime, CancellationToken ct = default)
        {
            if (audioSource == null)
            {
                return;
            }

            float startVolume = audioSource.volume;
            float elapsedTime = 0f;

            try
            {
                while (elapsedTime < fadeTime && !ct.IsCancellationRequested)
                {
                    elapsedTime += Time.deltaTime;
                    float t = Mathf.Clamp01(elapsedTime / fadeTime);
                    audioSource.volume = Mathf.Lerp(startVolume, 0f, t);

                    await UniTask.Yield(PlayerLoopTiming.Update, ct);
                }

                if (!ct.IsCancellationRequested)
                {
                    audioSource.volume = 0f;
                }
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[AudioGlobalControl] BGM淡出异常: {e.Message}");
            }
        }

        /// <summary>
        /// 获取音量参数名称
        /// </summary>
        private string GetVolumeParameterName(AudioType audioType)
        {
            switch (audioType)
            {
                case AudioType.BGM:
                    return _bgmVolumeParameterName;
                case AudioType.SFX_2D:
                    return _sfx2DVolumeParameterName;
                case AudioType.SFX_3D:
                    return _sfx3DVolumeParameterName;
                default:
                    return null;
            }
        }

        /// <summary>
        /// 获取静音时的dB值（恢复音量）
        /// </summary>
        private float GetMuteDbValue(AudioType audioType)
        {
            float volume = GetGlobalVolume(audioType);
            return volume > 0.0001f ? Mathf.Log10(volume) * 20f : -80f;
        }
    }
}
